// 浅拷贝
let a = {
    age: 10,
    n: {
        name: '张三'
    },
    bor:undefined,
    fn:function (){
        console.log("hello")
    },
    [Symbol(123)]:{}
}

// 使用展开运算符拷贝的对象时是浅拷贝
let b = {...a}

// a.n.name = "李四"
// console.log(b) //=> { age: 10, n: { name: '李四' } }

// 使用 JSON.parse(JSON.stringify(a)) 会导致function、undefined、symbol等类型无法拷贝
// let c = JSON.parse(JSON.stringify(a))
// console.log(c) //=> { age: 10, n: { name: '张三' } }

// 使用递归实现对象深拷贝
function cloneDeep(obj,hash = new WeakMap()){
    if(typeof obj === "object" && obj !== null){
        // 解决循环引用问题，如果这个对象在map存在了就不走递归了
        if(hash.has(obj)) return hash.get(obj)
        // 通过获取对象的constructor得到构造函数，如果是数组就返回数据，如果是对象就返回对象
        const copy = new obj.constructor
        hash.set(obj,copy)
        for (const key in obj) {
            if(obj.hasOwnProperty(key)){
                copy[key] = cloneDeep(obj[key])
            }
        }
        return copy
    }else {
        return obj
    }
}

let d = cloneDeep(a)
console.log(d)

let obj = {}
let arr = []
console.log(obj.constructor) //=> [Function: Object]
console.log(arr.constructor) //=> [Function: Array]


// 第三方库使用 lodash
// npm i --save lodash
import lodash from 'lodash'
let e = lodash.cloneDeep(a)
console.log(e)

